home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / cpptask.exe / TSKTIM.ASM < prev    next >
Assembly Source File  |  1991-07-26  |  6KB  |  267 lines

  1. ;
  2. ;    CTask - Timer interrupt handler (IBM specific)
  3. ;
  4. ;    Public Domain Software written by
  5. ;        Thomas Wagner
  6. ;        Patschkauer Weg 31
  7. ;        D-1000 Berlin 33
  8. ;        West Germany
  9. ;
  10.     name    tsktim
  11.     .model    large
  12. ;
  13.     public    _tsk_install_timer
  14.     public    _tsk_remove_timer
  15.     public    _tsk_chain_timer
  16. ;
  17.     include    tsk.mac
  18. ;
  19. timer    equ    40h            ; 8253 timer base I/O address
  20. inta00    equ    20h            ; 8259 int controller base
  21. eoi        equ    20h            ; unspecific EOI
  22. ;
  23. intseg    segment at 0
  24. ;
  25.         org    8*4
  26. tintofs        dw    ?        ; timer interrupt entry
  27. tintseg        dw    ?
  28. ;
  29. intseg    ends
  30. ;
  31. ;       declare pointers to two counters created automatically
  32. ;
  33.     extrn    _tsk_timer_counter:word
  34.     extrn    _tsk_int9_counter:word
  35. ;
  36.     .data?
  37. ;
  38. ;
  39. divisor        dw    ?
  40. timflag        dw    ?
  41. timcnt        dw    ?
  42. sys_ticks    dw    ?
  43. ;
  44. @curseg ends
  45. ;
  46. ;       function _sched_int defined in tskasm.asm
  47. ;
  48.     extrn    _sched_int:far
  49. ;
  50. ;       function _asm_inc_counter defined as:
  51. ;         extern "C" void asm_inc_counter(counterptr cnt)
  52. ;       in counter.cpp
  53. ;
  54.     extrn    _asm_inc_counter:far
  55. ;
  56.     .code
  57. ;
  58. timer_save    label    dword        ; in CSEG to allow addressing
  59. tsofs        dw    ?
  60. tsseg        dw    ?
  61. ;
  62. ;----------------------------------------------------------------------
  63. ;
  64. ;    timer interrupt handler
  65. ;
  66. timer_int    proc    far
  67.     sti
  68.     push    ds
  69.     push    ax
  70.     mov    ax,SEG dgroup
  71.     mov    ds,ax
  72. ;
  73.     cmp    timflag,1        ; initialisation ?
  74.     jne    no_init
  75. ;
  76. ;    Install timer
  77. ;
  78.     mov    timflag,0        ; signal init ready
  79.     mov    timcnt,1
  80.     mov    al,36h
  81.     out    timer+3,al        ; setup to load divisor
  82.     mov    al,byte ptr divisor
  83.     out    timer,al        ; lsb
  84.     mov    al,byte ptr divisor+1
  85.     out    timer,al        ; msb
  86.     jmp    short no_uninit
  87. ;
  88. no_init:
  89.     cmp    timflag,2        ; un-install flag set?
  90.     jne    no_uninit        ; no un-install if not
  91. ;
  92. ;       Un-Install timer (wait until system tick count reached)
  93. ;
  94. timdec:
  95.     cli
  96.     dec    timcnt            ; decrement tick count
  97.     jz    uninit            ; go un-install if zero
  98.     mov    al,eoi            ; else just issue EOI
  99.     out    inta00,al
  100.     pop    ax
  101.     pop    ds
  102.     iret                ; do nothing while waiting for uninit
  103. ;
  104. ;--------------------------------------------------------------------
  105. ;
  106. ;    Normal timer tick. The tick counter is incremented, and
  107. ;    the interrupt controller is checked for other pending interrupts.
  108. ;    If the timer tick occurred during processing of another interrupt,
  109. ;    we may not call the scheduler, since this would delay the
  110. ;    interrupt handler.
  111. ;
  112. ;    Note that an EOI is issued here to allow interrupts to occur
  113. ;    during further processing. The original INT 9 handler will be
  114. ;    chained to from a special task. The reason behind this is that
  115. ;    some TSR's link into the timer interrupt and may do some lengthy
  116. ;    processing there. To allow the TSR to be preempted, we must use
  117. ;    a task for the INT 9 processing.
  118. ;
  119. no_uninit:
  120.     push    es            ; save other regs
  121.     push    bx
  122.     push    cx
  123.     push    dx
  124.     mov    ax,ds
  125.     mov    es,ax
  126.     mov    ax,offset _tsk_timer_counter
  127.     push    ds
  128.     push    ax
  129.     call    _asm_inc_counter        ; increase timer tick counter
  130.     add    sp,4
  131. ;
  132. ;    Now the timer counter is decremented. If it is zero,
  133. ;    we must chain to the original INT 9, so the counter for
  134. ;    the chain task is incremented.
  135. ;
  136.     dec    timcnt            ; decrement tick count
  137.     jnz    no_pass            ; pass on this int if zero
  138. ;
  139.     mov    ax,sys_ticks
  140.     mov    timcnt,ax        ; re-init tick counter
  141. ;
  142.     mov    ax,offset _tsk_int9_counter
  143.     push    ds
  144.     push    ax
  145.         call    _asm_inc_counter        ; increase timer tick counter
  146.     add    sp,4
  147. ;
  148. no_pass:
  149.     pop    dx
  150.     pop    cx
  151.     pop    bx
  152.     pop    es
  153. ;
  154.     cli
  155.     mov    al,eoi            ; issue EOI
  156.     out    inta00,al
  157.     mov    al,0bh            ; access int control reg
  158.     out    inta00,al
  159.     in    al,inta00        ; ints pending?
  160.     or    al,al
  161.     pop    ax
  162.     pop    ds
  163.     jnz    no_sch            ; don't schedule if other ints active
  164.     jmp    _sched_int        ; else schedule
  165. ;
  166. no_sch:
  167.     iret
  168. ;
  169. ;------------------------------------------------------------------------
  170. ;
  171. ;    Uninstall timer int handler
  172. ;
  173. uninit:
  174.     mov    timflag,0        ; mark un-install complete
  175.     mov    al,36h            ; setup to load divisor
  176.     out    timer+3,al
  177.     mov    al,0            ; divisor 0 means 65536
  178.     out    timer,al        ; lsb
  179.     out    timer,al        ; msb
  180.     push    es
  181.     xor    ax,ax
  182.     mov    es,ax
  183.     assume    es:intseg
  184.     mov    ax,cs:tsofs        ; restore vector
  185.     mov    tintofs,ax
  186.     mov    ax,cs:tsseg
  187.     mov    tintseg,ax
  188.     assume    es:nothing
  189.     pop    es
  190.     pop    ax
  191.     pop    ds
  192.     jmp    cs:timer_save        ; pass on interrupt
  193. ;
  194. timer_int    endp
  195. ;
  196. ;----------------------------------------------------------------------
  197. ;
  198. ;    void far tsk_chain_timer (void)
  199. ;
  200. ;       Pass timer tick on to interrupt 9 chain.
  201. ;
  202. _tsk_chain_timer    proc    far
  203. ;
  204.     pushf
  205.     cli
  206.     call    cs:timer_save
  207.     ret
  208. ;
  209. _tsk_chain_timer    endp
  210. ;
  211. ;
  212. ;    void far tsk_install_timer (word divisor, word sys_ticks)
  213. ;
  214. ;    This routine installs the timer tick int handler.
  215. ;    The timer chip is reprogrammed on the next tick.
  216. ;
  217. _tsk_install_timer    proc    far
  218. ;
  219.     push    bp
  220.     mov    bp,sp
  221.     mov    ax,6[bp]
  222.     mov    divisor,ax
  223.     mov    ax,8[bp]
  224.     mov    sys_ticks,ax
  225.     mov    timflag,1        ; set init-flag
  226.     xor    ax,ax
  227.     mov    es,ax            ; establish addressing for intseg
  228.     assume    es:intseg
  229. ;
  230.     mov    ax,tintofs        ; save old timer int addr
  231.     mov    tsofs,ax
  232.     mov    ax,tintseg
  233.     mov    tsseg,ax
  234.     cli
  235.     mov    tintofs,offset timer_int ; set new timer int addr
  236.     mov    tintseg,cs
  237.     sti
  238.     assume    es:nothing
  239. wait_set:
  240.     cmp    timflag,0        ; wait until timer started
  241.     jne    wait_set
  242.     pop    bp
  243.     ret
  244. ;
  245. _tsk_install_timer    endp
  246. ;
  247. ;
  248. ;    void far tsk_remove_timer (void)
  249. ;
  250. ;    This routine un-installs the timer tick int handler.
  251. ;    The timer chip is reprogrammed & the interrupt vector
  252. ;    restored when the system tick count reaches zero.
  253. ;
  254. _tsk_remove_timer    proc    far
  255. ;
  256.     mov    timflag,2        ; set un-init flag for timer
  257. wait_tim:
  258.         sti                             ; just to be safe
  259.     cmp    timflag,0        ; wait until int un-installed
  260.     jne    wait_tim
  261.     ret
  262. ;
  263. _tsk_remove_timer    endp
  264. ;
  265.     end
  266.  
  267.